/** ****************************************************************************
 * CopyRight (C) 2012 Sharadendu Sinha.
 * Licensing : FreeBSD 
 *
 * @(#) $Id$
 */
package com.sps.signalling;

import java.util.List;
import java.util.concurrent.Executor;

import com.sps.signalling.Slot.SlotHandler;

/**
 * This defines the base interface for {@link Slot}s and {@link Signal}
 * 
 * @see Signal
 * @see Slot
 * @version 1.1
 * @author sharadendu
 */
public interface Invokable
{
	/**
	 * There can be two types of invokable , a {@link Signal} and
	 * {@link Slot}
	 * 
	 * @version 1.1
	 * @author sharadendu
	 */
	enum Type {
		SIGNAL, SLOT
	}

	/**
	 * When a signal is invoked it results in the signal being emitted and if it
	 * is invoked for a slot , it results in the slot handler being invoked
	 * Every time a slot is invoked, its {@link SlotHandler} will be invoked via
	 * {@link Executor} provided by the {@link SlotProvider}. By default all
	 * connections are
	 * {@link com.sps.signalling.InvokableConnection.Type#DIRECT} The default
	 * {@link Executor} provided by the {@link SlotProvider} invokes the
	 * {@link SlotHandler} in the same thread. However if the invocation is to
	 * be done on seperate Thread, the sub classes of {@link SignallingEntity}
	 * should override
	 * {@link SlotProvider#getExecutor(com.sps.signalling.InvokableConnection.Type)}
	 * 
	 * @param connectionType {@link com.sps.signalling.InvokableConnection.Type}
	 * @param paramObjects invocation parameters
	 */
	void invoke(InvokableConnection.Type connectionType, Object... paramObjects);

	/**
	 * @return name of this invokable
	 */
	String getName();

	/**
	 * @return {@link Type} of this invokable
	 */
	Type getType();

	/**
	 * For a {@link Signal} it is a {@link SignalEmmiter} and for a Slot
	 * {@link Slot} it is {@link SlotProvider}. This typically is the class that
	 * created the {@link Signal} or {@link Slot}
	 * 
	 * @return {@link InvokableProvider}
	 */
	InvokableProvider getProvider();

	/**
	 * This method returns a {@link InvokableConnection} if there exists one
	 * with the supplied parameter.
	 * 
	 * @param signal {@link Invokable}
	 * @param invokable {@link Invokable}
	 * @param type {@link Type}
	 * @return {@link InvokableConnection} if one exists else null will be
	 *         returned
	 */
	InvokableConnection getConnection(Invokable signal, Invokable invokable,
		InvokableConnection.Type type);

	/**
	 * Add a new {@link InvokableConnection} to the existing
	 * {@link InvokableConnection}s
	 * 
	 * @param connection {@link InvokableConnection}
	 */
	void addConnection(InvokableConnection connection);

	/**
	 * Remove this {@link InvokableConnection} from existing
	 * {@link InvokableConnection}s
	 * 
	 * @param connection {@link InvokableConnection}
	 */
	void removeConnection(InvokableConnection connection);

	/**
	 * Clears all connections assiciated with this {@link Invokable}
	 */
	void resetConnections();

	/**
	 * Returns all the connections associated with this {@link Invokable}
	 * 
	 * @return {@link List} for all {@link InvokableConnection}s
	 */
	List<InvokableConnection> getConnections();
}
